kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Fix HTML report generation v2
@ 2011-04-29  3:49 Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 1/4] tools/html_report: Make html report generation autotest generic Lucas Meneghel Rodrigues
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-29  3:49 UTC (permalink / raw)
  To: autotest; +Cc: kvm

Made HTML report generation generic and useable by any autotest
client job, fixed up some bugs in HTML report code. Now it'll
be easier to browse and visualize results without the autotest web
interface.

Lucas Meneghel Rodrigues (4):
  tools/html_report: Make html report generation autotest generic
  job: Write a job HTML report for every autotest client job
  virt.virt_utils: Get rid of create_report function
  KVM test: control: Get rid of report generation code

 client/bin/job.py           |    4 +
 client/tests/kvm/control    |    3 -
 client/tools/html_report.py |  158 ++++++++++++++++++++++++++++---------------
 client/virt/virt_utils.py   |   12 ---
 4 files changed, 108 insertions(+), 69 deletions(-)

-- 
1.7.4.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] tools/html_report: Make html report generation autotest generic
  2011-04-29  3:49 [PATCH 0/4] Fix HTML report generation v2 Lucas Meneghel Rodrigues
@ 2011-04-29  3:49 ` Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 2/4] job: Write a job HTML report for every autotest client job Lucas Meneghel Rodrigues
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-29  3:49 UTC (permalink / raw)
  To: autotest; +Cc: kvm

The html report tool was a bit too tied to KVM autotest, and that
was not necessary. Turn it into a generic module that can be used
by any autotest job, encapsulate the main worker function into
autotest API so we don't need to exec it in a subshell, fix naming
of the report and CSS details.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/tools/html_report.py |  158 ++++++++++++++++++++++++++++---------------
 1 files changed, 104 insertions(+), 54 deletions(-)

diff --git a/client/tools/html_report.py b/client/tools/html_report.py
index 8b4b109..7b17a75 100755
--- a/client/tools/html_report.py
+++ b/client/tools/html_report.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 """
-Script used to parse the test results and generate an HTML report.
+Module used to parse the autotest job results and generate an HTML report.
 
 @copyright: (c)2005-2007 Matt Kruse (javascripttoolbox.com)
 @copyright: Red Hat 2008-2009
@@ -27,7 +27,6 @@ body {
     text-decoration:none;
     font:bold 2em/2em Arial, Helvetica, sans-serif;
     text-transform:none;
-    text-shadow: 2px 2px 2px #555;
     text-align: left;
     color:#555555;
     border-bottom: 1px solid #555555;
@@ -37,7 +36,6 @@ body {
         text-decoration:none;
         font:bold 16px Arial, Helvetica, sans-serif;
         text-transform:uppercase;
-        text-shadow: 2px 2px 2px #555;
         text-align: left;
         color:#555555;
     margin-bottom:0;
@@ -1374,21 +1372,27 @@ function processList(ul) {
 }
 """
 
-
-#################################################################
-##  This script gets kvm autotest results directory path as an ##
-##  input and create a single html formatted result page.      ##
-#################################################################
-
 stimelist = []
 
 
 def make_html_file(metadata, results, tag, host, output_file_name, dirname):
+    """
+    Create HTML file contents for the job report, to stdout or filesystem.
+
+    @param metadata: Dictionary with Job metadata (tests, exec time, etc).
+    @param results: List with testcase results.
+    @param tag: Job tag.
+    @param host: Client hostname.
+    @param output_file_name: Output file name. If empty string, prints to
+            stdout.
+    @param dirname: Prefix for HTML links. If empty string, the HTML links
+            will be relative to the results dir.
+    """
     html_prefix = """
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-<title>KVM Autotest Results</title>
+<title>Autotest job execution results</title>
 <style type="text/css">
 %s
 </style>
@@ -1407,14 +1411,13 @@ return true;
 <body>
 """ % (format_css, table_js, maketree_js)
 
-
     if output_file_name:
         output = open(output_file_name, "w")
     else:   #if no output file defined, print html file to console
         output = sys.stdout
     # create html page
     print >> output, html_prefix
-    print >> output, '<h2 id=\"page_title\">KVM Autotest Execution Report</h2>'
+    print >> output, '<h2 id=\"page_title\">Autotest job execution report</h2>'
 
     # formating date and time to print
     t = datetime.datetime.now()
@@ -1438,7 +1441,7 @@ return true;
         stat_str = ('From %d tests executed, %d have passed (%d%% failures)' %
                     (total_executed, total_passed, failed_perct))
 
-    kvm_ver_str = metadata['kvmver']
+    kvm_ver_str = metadata.get('kvmver', None)
 
     print >> output, '<table class="stats2">'
     print >> output, '<tr><td>HOST</td><td>:</td><td>%s</td></tr>' % host
@@ -1446,10 +1449,10 @@ return true;
     print >> output, '<tr><td>DATE</td><td>:</td><td>%s</td></tr>' % now.ctime()
     print >> output, '<tr><td>STATS</td><td>:</td><td>%s</td></tr>'% stat_str
     print >> output, '<tr><td></td><td></td><td></td></tr>'
-    print >> output, '<tr><td>KVM VERSION</td><td>:</td><td>%s</td></tr>' % kvm_ver_str
+    if kvm_ver_str is not None:
+        print >> output, '<tr><td>KVM VERSION</td><td>:</td><td>%s</td></tr>' % kvm_ver_str
     print >> output, '</table>'
 
-
     ## print test results
     print >> output, '<br>'
     print >> output, '<h2 id=\"page_sub_title\">Test Results</h2>'
@@ -1529,6 +1532,12 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
 
 
 def parse_result(dirname, line):
+    """
+    Parse job status log line.
+
+    @param dirname: Job results dir
+    @param line: Status log line.
+    """
     parts = line.split()
     if len(parts) < 4:
         return None
@@ -1556,7 +1565,7 @@ def parse_result(dirname, line):
         # assign actual values
         rx = re.compile('^(\w+)\.(.*)$')
         m1 = rx.findall(parts[3])
-        result['testcase'] = m1[0][1]
+        result['testcase'] = str(tag)
         result['title'] = str(tag)
         result['status'] = parts[1]
         if result['status'] != 'GOOD':
@@ -1572,10 +1581,16 @@ def parse_result(dirname, line):
 
 
 def get_exec_log(resdir, tag):
-    stdout_file = os.path.join(resdir, tag) + '/debug/stdout'
-    stderr_file = os.path.join(resdir, tag) + '/debug/stderr'
-    status_file = os.path.join(resdir, tag) + '/status'
-    dmesg_file = os.path.join(resdir, tag) + '/sysinfo/dmesg'
+    """
+    Get job execution summary.
+
+    @param resdir: Job results dir.
+    @param tag: Job tag.
+    """
+    stdout_file = os.path.join(resdir, tag, 'debug', 'stdout')
+    stderr_file = os.path.join(resdir, tag, 'debug', 'stderr')
+    status_file = os.path.join(resdir, tag, 'status')
+    dmesg_file = os.path.join(resdir, tag, 'sysinfo', 'dmesg')
     log = ''
     log += '<br><b>STDERR:</b><br>'
     log += get_info_file(stderr_file)
@@ -1589,6 +1604,13 @@ def get_exec_log(resdir, tag):
 
 
 def get_info_file(filename):
+    """
+    Gets the contents of an autotest info file.
+
+    It also and highlights the file contents with possible problems.
+
+    @param filename: Info file path.
+    """
     data = ''
     errors = re.compile(r"\b(error|fail|failed)\b", re.IGNORECASE)
     if os.path.isfile(filename):
@@ -1610,8 +1632,10 @@ def get_info_file(filename):
     return data
 
 
-
 def usage():
+    """
+    Print stand alone program usage.
+    """
     print 'usage:',
     print 'make_html_report.py -r <result_directory> [-f output_file] [-R]'
     print '(e.g. make_html_reporter.py -r '\
@@ -1626,6 +1650,9 @@ def get_keyval_value(result_dir, key):
     """
     Return the value of the first appearance of key in any keyval file in
     result_dir. If no appropriate line is found, return 'Unknown'.
+
+    @param result_dir: Path that holds the keyval files.
+    @param key: Specific key we're retrieving.
     """
     keyval_pattern = os.path.join(result_dir, "kvm.*", "keyval")
     keyval_lines = commands.getoutput(r"grep -h '\b%s\b.*=' %s"
@@ -1643,15 +1670,69 @@ def get_kvm_version(result_dir):
     """
     Return an HTML string describing the KVM version.
 
-        @param result_dir: An Autotest job result dir
+    @param result_dir: An Autotest job result dir.
     """
     kvm_version = get_keyval_value(result_dir, "kvm_version")
     kvm_userspace_version = get_keyval_value(result_dir,
                                              "kvm_userspace_version")
+    if kvm_version == "Unknown" or kvm_userspace_version == "Unknown":
+        return None
     return "Kernel: %s<br>Userspace: %s" % (kvm_version, kvm_userspace_version)
 
 
+def create_report(dirname, html_path='', output_file_name=None):
+    """
+    Create an HTML report with info about an autotest client job.
+
+    If no relative path (html_path) or output file name provided, an HTML
+    file in the toplevel job results dir called 'job_report.html' will be
+    created, with relative links.
+
+    @param html_path: Prefix for the HTML links. Useful to specify absolute
+            in the report (not wanted most of the time).
+    @param output_file_name: Path to the report file.
+    """
+    res_dir = os.path.abspath(dirname)
+    tag = res_dir
+    status_file_name = os.path.join(dirname, 'status')
+    sysinfo_dir = os.path.join(dirname, 'sysinfo')
+    host = get_info_file(os.path.join(sysinfo_dir, 'hostname'))
+    rx = re.compile('^\s+[END|START].*$')
+    # create the results set dict
+    results_data = []
+    if os.path.exists(status_file_name):
+        f = open(status_file_name, "r")
+        lines = f.readlines()
+        f.close()
+        for line in lines:
+            if rx.match(line):
+                result_dict = parse_result(dirname, line)
+                if result_dict:
+                    results_data.append(result_dict)
+    # create the meta info dict
+    metalist = {
+                'uname': get_info_file(os.path.join(sysinfo_dir, 'uname')),
+                'cpuinfo':get_info_file(os.path.join(sysinfo_dir, 'cpuinfo')),
+                'meminfo':get_info_file(os.path.join(sysinfo_dir, 'meminfo')),
+                'df':get_info_file(os.path.join(sysinfo_dir, 'df')),
+                'modules':get_info_file(os.path.join(sysinfo_dir, 'modules')),
+                'gcc':get_info_file(os.path.join(sysinfo_dir, 'gcc_--version')),
+                'dmidecode':get_info_file(os.path.join(sysinfo_dir, 'dmidecode')),
+                'dmesg':get_info_file(os.path.join(sysinfo_dir, 'dmesg')),
+    }
+    if get_kvm_version(dirname) is not None:
+        metalist['kvm_ver'] = get_kvm_version(dirname)
+
+    if output_file_name is None:
+        output_file_name = os.path.join(dirname, 'job_report.html')
+    make_html_file(metalist, results_data, tag, host, output_file_name,
+                   html_path)
+
+
 def main(argv):
+    """
+    Parses the arguments and executes the stand alone program.
+    """
     dirname = None
     output_file_name = None
     relative_path = False
@@ -1682,38 +1763,7 @@ def main(argv):
     if dirname:
         if os.path.isdir(dirname): # TBD: replace it with a validation of
                                    # autotest result dir
-            res_dir = os.path.abspath(dirname)
-            tag = res_dir
-            status_file_name = dirname + '/status'
-            sysinfo_dir = dirname + '/sysinfo'
-            host = get_info_file('%s/hostname' % sysinfo_dir)
-            rx = re.compile('^\s+[END|START].*$')
-            # create the results set dict
-            results_data = []
-            if os.path.exists(status_file_name):
-                f = open(status_file_name, "r")
-                lines = f.readlines()
-                f.close()
-                for line in lines:
-                    if rx.match(line):
-                        result_dict = parse_result(dirname, line)
-                        if result_dict:
-                            results_data.append(result_dict)
-            # create the meta info dict
-            metalist = {
-                        'uname': get_info_file('%s/uname' % sysinfo_dir),
-                        'cpuinfo':get_info_file('%s/cpuinfo' % sysinfo_dir),
-                        'meminfo':get_info_file('%s/meminfo' % sysinfo_dir),
-                        'df':get_info_file('%s/df' % sysinfo_dir),
-                        'modules':get_info_file('%s/modules' % sysinfo_dir),
-                        'gcc':get_info_file('%s/gcc_--version' % sysinfo_dir),
-                        'dmidecode':get_info_file('%s/dmidecode' % sysinfo_dir),
-                        'dmesg':get_info_file('%s/dmesg' % sysinfo_dir),
-                        'kvmver':get_kvm_version(dirname)
-            }
-
-            make_html_file(metalist, results_data, tag, host, output_file_name,
-                           html_path)
+            create_report(dirname, html_path, output_file_name)
             sys.exit(0)
         else:
             print 'Invalid result directory <%s>' % dirname
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] job: Write a job HTML report for every autotest client job
  2011-04-29  3:49 [PATCH 0/4] Fix HTML report generation v2 Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 1/4] tools/html_report: Make html report generation autotest generic Lucas Meneghel Rodrigues
@ 2011-04-29  3:49 ` Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 3/4] virt.virt_utils: Get rid of create_report function Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 4/4] KVM test: control: Get rid of report generation code Lucas Meneghel Rodrigues
  3 siblings, 0 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-29  3:49 UTC (permalink / raw)
  To: autotest; +Cc: kvm

We have a tool that can generate such a file and it makes it
easier for people who don't have access to the autotest web
interface to analyze job results. With this, all client jobs
write such a file, so test writers don't have to worry about
it.

This change does not regress the job unittests.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/bin/job.py |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/client/bin/job.py b/client/bin/job.py
index 9effcdb..a792309 100644
--- a/client/bin/job.py
+++ b/client/bin/job.py
@@ -17,6 +17,7 @@ from autotest_lib.client.common_lib import base_job
 from autotest_lib.client.common_lib import error, barrier, log, logging_manager
 from autotest_lib.client.common_lib import base_packages, packages
 from autotest_lib.client.common_lib import global_config
+from autotest_lib.client.tools import html_report
 
 
 LAST_BOOT_TAG = object()
@@ -950,6 +951,9 @@ class base_client_job(base_job.base_job):
             self._tap.write()
             self._tap._write_tap_archive()
 
+        # write out a job HTML report
+        html_report.create_report(self.resultdir)
+
         # We are about to exit 'complete' so clean up the control file.
         dest = os.path.join(self.resultdir, os.path.basename(self._state_file))
         shutil.move(self._state_file, dest)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] virt.virt_utils: Get rid of create_report function
  2011-04-29  3:49 [PATCH 0/4] Fix HTML report generation v2 Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 1/4] tools/html_report: Make html report generation autotest generic Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 2/4] job: Write a job HTML report for every autotest client job Lucas Meneghel Rodrigues
@ 2011-04-29  3:49 ` Lucas Meneghel Rodrigues
  2011-04-29  3:49 ` [PATCH 4/4] KVM test: control: Get rid of report generation code Lucas Meneghel Rodrigues
  3 siblings, 0 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-29  3:49 UTC (permalink / raw)
  To: autotest; +Cc: kvm

As it has been transfered to the html_report module itself.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/virt/virt_utils.py |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/client/virt/virt_utils.py b/client/virt/virt_utils.py
index 97a652d..8fa64ca 100644
--- a/client/virt/virt_utils.py
+++ b/client/virt/virt_utils.py
@@ -1187,18 +1187,6 @@ def run_tests(parser, job):
     return not failed
 
 
-def create_report(report_dir, results_dir):
-    """
-    Creates a neatly arranged HTML results report in the results dir.
-
-    @param report_dir: Directory where the report script is located.
-    @param results_dir: Directory where the results will be output.
-    """
-    reporter = os.path.join(report_dir, 'html_report.py')
-    html_file = os.path.join(results_dir, 'results.html')
-    os.system('%s -r %s -f %s -R' % (reporter, results_dir, html_file))
-
-
 def display_attributes(instance):
     """
     Inspects a given class instance attributes and displays them, convenient
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] KVM test: control: Get rid of report generation code
  2011-04-29  3:49 [PATCH 0/4] Fix HTML report generation v2 Lucas Meneghel Rodrigues
                   ` (2 preceding siblings ...)
  2011-04-29  3:49 ` [PATCH 3/4] virt.virt_utils: Get rid of create_report function Lucas Meneghel Rodrigues
@ 2011-04-29  3:49 ` Lucas Meneghel Rodrigues
  3 siblings, 0 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-29  3:49 UTC (permalink / raw)
  To: autotest; +Cc: kvm

As this is now handled by autotest and control file
writers don't have to worry about it anymore.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/tests/kvm/control |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/client/tests/kvm/control b/client/tests/kvm/control
index 6437d88..c887a3e 100644
--- a/client/tests/kvm/control
+++ b/client/tests/kvm/control
@@ -67,6 +67,3 @@ if args:
 parser.parse_string(str)
 
 virt_utils.run_tests(parser, job)
-
-# Generate a nice HTML report inside the job's results dir
-virt_utils.create_report(kvm_test_dir, job.resultdir)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-04-29  3:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-29  3:49 [PATCH 0/4] Fix HTML report generation v2 Lucas Meneghel Rodrigues
2011-04-29  3:49 ` [PATCH 1/4] tools/html_report: Make html report generation autotest generic Lucas Meneghel Rodrigues
2011-04-29  3:49 ` [PATCH 2/4] job: Write a job HTML report for every autotest client job Lucas Meneghel Rodrigues
2011-04-29  3:49 ` [PATCH 3/4] virt.virt_utils: Get rid of create_report function Lucas Meneghel Rodrigues
2011-04-29  3:49 ` [PATCH 4/4] KVM test: control: Get rid of report generation code Lucas Meneghel Rodrigues

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).