commit 1a943fc7c4342e1cce59eef49a1e2d43c705db06
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Wed Sep 4 13:36:05 2013 +0200
NetTestResultSerializer: new results reimplementation
This commit reimplements the result serializer so that it doesn't
automatically create a DOM tree out of the supplied results. Instead
results are stored in a nice dictionary hierarchy.
This changed combined with moving the res_data formatting done on slaves
makes it very easy to print the summary. And at the same time be able to
easily create an xml file.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst-ctl | 2 +-
lnst/Controller/NetTestController.py | 2 +
lnst/Controller/NetTestResultSerializer.py | 265 +++++++++-------------------
3 files changed, 91 insertions(+), 178 deletions(-)
---
diff --git a/lnst-ctl b/lnst-ctl
index 55e2dd1..43770b2 100755
--- a/lnst-ctl
+++ b/lnst-ctl
@@ -183,7 +183,7 @@ def main():
if result_path:
result_path = os.path.expanduser(result_path)
handle = open(result_path, "w")
- handle.write(str(res_serializer))
+ handle.write(res_serializer.get_result_xml())
handle.close()
if __name__ == "__main__":
diff --git a/lnst/Controller/NetTestController.py b/lnst/Controller/NetTestController.py
index c7d1fab..8045aa7 100644
--- a/lnst/Controller/NetTestController.py
+++ b/lnst/Controller/NetTestController.py
@@ -495,6 +495,8 @@ class NetTestController:
command["seconds"]),
"msg": "",
"res_data": None}
+ if self._res_serializer:
+ self._res_serializer.add_cmd_result(command, cmd_res)
return cmd_res
machine_id = command["machine"]
diff --git a/lnst/Controller/NetTestResultSerializer.py
b/lnst/Controller/NetTestResultSerializer.py
index d245568..514988b 100644
--- a/lnst/Controller/NetTestResultSerializer.py
+++ b/lnst/Controller/NetTestResultSerializer.py
@@ -44,213 +44,71 @@ def get_node_val(node):
class NetTestResultSerializer:
def __init__(self):
- impl = getDOMImplementation()
- self._dom = impl.createDocument(None, "results", None)
- self._top_el = self._dom.documentElement
- self._cur_recipe_el = None
- self._cur_cmd_seq_el = None
-
- def __str__(self):
- return self._dom.toprettyxml()
+ self._results = []
def add_recipe(self, name):
- recipe_el = self._dom.createElement("recipe")
- recipe_el.setAttribute("name", name)
- recipe_el.setAttribute("result", "FAIL")
- self._top_el.appendChild(recipe_el)
- self._cur_recipe_el = recipe_el
- self._cur_cmd_seq_el = None
+ recipe_result = {"name": name,
+ "result": "FAIL",
+ "tasks": []}
+ self._results.append(recipe_result)
def set_recipe_result(self, result):
if result and result["passed"]:
- self._cur_recipe_el.setAttribute("result", "PASS")
+ self._results[-1]["result"] = "PASS"
else:
- self._cur_recipe_el.setAttribute("result", "FAIL")
+ self._results[-1]["result"] = "FAIL"
+
if "err_msg" in result:
- err_el = self._dom.createElement("error_message")
- err_text = self._dom.createTextNode(result["err_msg"])
- err_el.appendChild(err_text)
- self._cur_recipe_el.appendChild(err_el)
+ self._results[-1]["err_msg"] = result["err_msg"]
def add_task(self):
- cmd_seq_el = self._dom.createElement("command_sequence")
- self._cur_recipe_el.appendChild(cmd_seq_el)
- self._cur_cmd_seq_el = cmd_seq_el
+ self._results[-1]["tasks"].append([])
def add_cmd_result(self, command, cmd_res):
- command_el = self._dom.createElement("command")
- self._cur_cmd_seq_el.appendChild(command_el)
-
- for key in command:
- if key == "options":
- continue
- command_el.setAttribute(key, str(command[key]))
-
- result_el = self._dom.createElement("result")
- command_el.appendChild(result_el)
-
- if cmd_res["passed"]:
- res = "PASS"
- else:
- res = "FAIL"
- result_el.setAttribute("result", res)
-
- if "err_msg" in cmd_res:
- err_el = self._dom.createElement("error_message")
- err_text = self._dom.createTextNode(cmd_res["err_msg"])
- err_el.appendChild(err_text)
- result_el.appendChild(err_el)
-
- if "res_data" in cmd_res:
- res_data_el = self._dom.createElement("result_data")
- serialize_obj(cmd_res["res_data"], self._dom, res_data_el)
- command_el.appendChild(res_data_el)
+ self._results[-1]["tasks"][-1].append((command, cmd_res))
def print_summary(self):
output_pairs = []
- for recipe in self._top_el.getElementsByTagName("recipe"):
- recipe_name = recipe.getAttribute("name")
- recipe_res = recipe.getAttribute("result")
- output_pairs.append((recipe_name, recipe_res))
-
- if recipe_res == "FAIL":
- err_node = None
- for child in recipe.childNodes:
- if child.nodeName == "error_message":
- err_node = child
- break
- if err_node:
- text = get_node_val(err_node)
- output_pairs.append((4*" "+"error message:
"+text, ""))
+ for recipe in self._results:
+ output_pairs.append((recipe["name"], recipe["result"]))
+
+ if recipe["result"] == "FAIL" and \
+ "err_msg" in recipe and recipe["err_msg"] !=
"":
+ err_msg = recipe["err_msg"]
+ output_pairs.append((4*" " + "error message:" +
err_msg, ""))
seq_num = 1
- for cmd_seq in recipe.getElementsByTagName("command_sequence"):
- command_sequence = 4*" "+"task: %s" % seq_num
- output_pairs.append((command_sequence, ""))
+ for task in recipe["tasks"]:
+ output_pairs.append((4*" " + "task: %s" %
seq_num,""))
- seq_num = seq_num + 1
+ seq_num += 1
- for command in cmd_seq.getElementsByTagName("command"):
- self._format_command(command, output_pairs)
+ for cmd, cmd_res in task:
+ self._format_command(cmd, cmd_res, output_pairs)
self._print_pairs(output_pairs)
- def _format_command(self, command, output_pairs):
- cmd_type = command.getAttribute("type")
- if cmd_type == "test":
- self._format_test_command(command, output_pairs)
- elif cmd_type == "wait":
- self._format_wait_command(command, output_pairs)
- elif cmd_type == "intr":
- self._format_intr_command(command, output_pairs)
- elif cmd_type == "kill":
- self._format_kill_command(command, output_pairs)
- elif cmd_type == "ctl_wait":
- self._format_ctl_wait_command(command, output_pairs)
- elif cmd_type == "exec":
- self._format_exec_command(command, output_pairs)
- elif cmd_type == "config":
- self._format_config(command, output_pairs)
-
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
-
- if cmd_res == "FAIL":
- err_node = result_node.getElementsByTagName("error_message")
- if len(err_node) != 0:
- err_node = err_node[0]
- text = get_node_val(err_node)
- output_pairs.append((12*" "+"error message: "+text,
""))
-
- def _format_test_command(self, command, output_pairs):
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
-
- cmd_val = command.getAttribute("module")
- cmd_type = command.getAttribute("type")
- if command.hasAttribute("bg_id"):
- bg_id = " bg_id: %s" % command.getAttribute("bg_id")
- else:
- bg_id = ""
- cmd = 8*" "+"%-14s%s%s" %(cmd_type, cmd_val, bg_id)
- output_pairs.append((cmd, cmd_res))
-
- def _format_wait_command(self, command, output_pairs):
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
-
- cmd_val = command.getAttribute("proc_id")
- cmd_type = command.getAttribute("type")
- if command.hasAttribute("bg_id"):
- bg_id = " bg_id: %s" % command.getAttribute("bg_id")
+ def _format_command(self, command, cmd_res, output_pairs):
+ if cmd_res["passed"]:
+ res = "PASS"
else:
- bg_id = ""
- cmd = 8*" "+"%-13s id: %s%s" %(cmd_type, cmd_val, bg_id)
- output_pairs.append((cmd, cmd_res))
-
- def _format_intr_command(self, command, output_pairs):
- self._format_wait_command(command, output_pairs)
-
- def _format_kill_command(self, command, output_pairs):
- self._format_wait_command(command, output_pairs)
+ res = "FAIL"
+ output_pairs.append((8*" " + cmd_res["res_header"], res))
- def _format_exec_command(self, command, output_pairs):
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
+ if "msg" in cmd_res and cmd_res["msg"] != "":
+ output_pairs.append((12*" " + "message: " +
cmd_res["msg"], ""))
- cmd_val = command.getAttribute("command")
- cmd_type = command.getAttribute("type")
- if command.hasAttribute("bg_id"):
- bg_id = " bg_id: %s" % command.getAttribute("bg_id")
- else:
- bg_id = ""
- cmd = 8*" "+"%-14s%s%s" %(cmd_type, cmd_val, bg_id)
- output_pairs.append((cmd, cmd_res))
-
- def _format_ctl_wait_command(self, command, output_pairs):
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
-
- cmd_val = command.getAttribute("seconds")
- cmd_type = command.getAttribute("type")
- cmd = 8*" "+"%-14s%ss" %(cmd_type, cmd_val)
- output_pairs.append((cmd, cmd_res))
-
- def _format_config(self, command, output_pairs):
- result_node = command.getElementsByTagName("result")[0]
- cmd_res = result_node.getAttribute("result")
-
- cmd_type = command.getAttribute("type")
- if command.hasAttribute("bg_id"):
- bg_id = " bg_id: %s" % command.getAttribute("bg_id")
- else:
- bg_id = ""
- cmd = 8*" "+"%-14s%s" %(cmd_type, bg_id)
- output_pairs.append((cmd, cmd_res))
-
- result_data_nodes = command.getElementsByTagName("result_data")
- if len(result_data_nodes) != 0:
- result_data_node = result_data_nodes[0]
- options_nodes = result_data_node.getElementsByTagName("options")
- for options_node in options_nodes:
- for option in
options_node.getElementsByTagName("options_item"):
- previous_node =
option.getElementsByTagName("previous_val")[0]
- current_node =
option.getElementsByTagName("current_val")[0]
- name_node = option.getElementsByTagName("name")[0]
- previous_val = get_node_val(previous_node)
- current_val = get_node_val(current_node)
- name = get_node_val(name_node)
- opt_left = 12*" "+"%s" % name
- opt_right = "previous: %s current: %s" \
- % (previous_val, current_val)
- output_pairs.append((opt_left, opt_right))
+ if "report" in cmd_res and cmd_res["report"] !=
"":
+ for line in cmd_res["report"].splitlines():
+ out = decorate_with_preset(line, "faded")
+ output_pairs.append((12*" " + out, ""))
def _print_pairs(self, output_pairs):
max_left = 0
max_right = 0
for left, right in output_pairs:
- if len(left) > max_left and right != "":
+ if len(left) > max_left:
max_left = len(left)
if len(right) > max_right:
max_right = len(right)
@@ -282,3 +140,56 @@ class NetTestResultSerializer:
output = left + " "
logging.info(" %s " % output)
logging.info("="*(full_length))
+
+ def get_result_xml(self):
+ impl = getDOMImplementation()
+ doc = impl.createDocument(None, "results", None)
+ top_el = doc.documentElement
+
+ for recipe in self._results:
+ recipe_el = doc.createElement("recipe")
+ recipe_el.setAttribute("name", recipe["name"])
+ recipe_el.setAttribute("result", recipe["result"])
+
+ top_el.appendChild(recipe_el)
+
+ if recipe["result"] == "FAIL" and \
+ "err_msg" in recipe and recipe["err_msg"] !=
"":
+ err_el = doc.createElement("error_message")
+ err_text = doc.createTextNode(recipe["err_msg"])
+ err_el.appendChild(err_text)
+ recipe_el.appendChild(err_el)
+
+ for task in recipe["tasks"]:
+ cmd_seq_el = doc.createElement("command_sequence")
+ recipe_el.appendChild(cmd_seq_el)
+
+ for cmd, cmd_res in task:
+ command_el = doc.createElement("command")
+ cmd_seq_el.appendChild(command_el)
+
+ for key in cmd:
+ if key == "options":
+ continue
+ command_el.setAttribute(key, str(cmd[key]))
+
+ result_el = doc.createElement("result")
+ command_el.appendChild(result_el)
+
+ if cmd_res["passed"]:
+ res = "PASS"
+ else:
+ res = "FAIL"
+ result_el.setAttribute("result", res)
+
+ if "msg" in cmd_res and cmd_res["msg"]:
+ msg_el = doc.createElement("message")
+ msg_text = doc.createTextNode(cmd_res["msg"])
+ msg_el.appendChild(msg_text)
+ result_el.appendChild(msg_el)
+
+ if "res_data" in cmd_res and
cmd_res["res_data"]:
+ res_data_el = doc.createElement("result_data")
+ serialize_obj(cmd_res["res_data"], doc, res_data_el)
+ command_el.appendChild(res_data_el)
+ return doc.toprettyxml()