[Xcb] [PATCH 2/2] Add tests/checklog2html.py

Daniel Martin consume.noise at gmail.com
Fri Aug 16 13:32:23 PDT 2013


Add checklog2html.py, a script to generate html out of CheckLog_xcb.xml.

Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
Quickly written replacement for the previously used xslt.

I didn't spend much time on comments. Because, I think it won't last
forever if we add more and real tests. I.e. if we're going to add tests
for requests that actually change/set something then we've to use an
xserver with the null driver (or something similar). Peter Hutterers
testsuite is able to do such things.

Until that it should be sufficient to generate html.

 tests/Makefile.am      |   4 +-
 tests/checklog2html.py | 181 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 2 deletions(-)
 create mode 100644 tests/checklog2html.py

diff --git a/tests/Makefile.am b/tests/Makefile.am
index ff90646..1a90317 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,7 +2,7 @@
 ## tests/Makefile.am
 ########################
 SUBDIRS = 
-EXTRA_DIST =
+EXTRA_DIST = checklog2html.py
 AM_MAKEFLAGS = -k
 AM_CFLAGS = -Wall -Werror @CHECK_CFLAGS@ -I$(top_srcdir)/src
 LDADD = @CHECK_LIBS@ $(top_builddir)/src/libxcb.la
@@ -13,7 +13,7 @@ check_PROGRAMS = check_all
 check_all_SOURCES =  check_all.c check_suites.h check_public.c
 
 check-local: check-TESTS
-	touch CheckLog.html
+	$(PYTHON) $(srcdir)/checklog2html.py CheckLog_xcb.xml > CheckLog.html
 
 CheckLog.html: $(check_PROGRAMS)
 	$(MAKE) $(AM_MAKEFLAGS) check;
diff --git a/tests/checklog2html.py b/tests/checklog2html.py
new file mode 100644
index 0000000..29fc21c
--- /dev/null
+++ b/tests/checklog2html.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+
+from string import Template
+from xml.etree.ElementTree import parse, XMLParser
+
+import sys
+import textwrap
+
+
+class Element(object):
+    def __init__(self, attrs):
+        super(Element, self).__init__()
+
+        self.attrs = attrs
+
+
+class TestSuites(Element):
+    _template = Template('''\
+    <html>
+        <head>
+            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+            <title>Test Suite Results</title>
+        </head>
+        <body>
+            $suites
+            <h3>Unit Test Statistics</h3>
+            <ul>
+                <li>date/time: $datetime</li>
+                <li>duration: $duration</li>
+            </ul>
+        </body>
+    </html>
+    ''')
+
+    def __init__(self, attrs):
+        super(TestSuites, self).__init__(attrs)
+
+        self.suites = []
+
+
+    def __str__(self):
+        suites = ""
+        for suite in self.suites:
+            suites += str(suite)
+
+        html = self._template.substitute(suites=suites, **self.attrs)
+        return textwrap.dedent(html)
+
+
+class Suite(Element):
+    _template = Template('''
+            <h2>Test Suite: $title</h2>
+            <center>
+                <table width="%80" border="1">
+                    <thead>
+                        <td>Test Path</td>
+                        <td>Test Function Location</td>
+                        <td>Iteration</td>
+                        <td>Duration</td>
+                        <td>C Identifier</td>
+                        <td>Test Case</td>
+                        <td>Result</td>
+                    </thead>
+                    $tests
+                </table>
+            </center>
+        ''')
+
+    def __init__(self, attrs):
+        super(Suite, self).__init__(attrs)
+
+        self.tests = []
+
+
+    def __str__(self):
+        tests = ""
+        for test in self.tests:
+            tests += str(test)
+
+        return self._template.substitute(tests=tests, **self.attrs)
+
+
+class Test(Element):
+    _color_map = {
+            'error':'yellow',
+            'failure':'red',
+            'success':'lime',
+            }
+    _template = Template('''
+                    <tr bgcolor="$color">
+                        <td>$path</td>
+                        <td>$fn</td>
+                        <td>$iteration</td>
+                        <td>$duration</td>
+                        <td>$id</td>
+                        <td>$description</td>
+                        <td>$message</td>
+                    </tr>
+            ''')
+
+    def __str__(self):
+        color = self._color_map[self.attrs['result']]
+
+        return self._template.substitute(color=color, **self.attrs)
+
+
+class CheckTreeBuild(object):
+    _obj_tags = ('suite', 'test', 'testsuites')
+    def __init__(self):
+        super(CheckTreeBuild, self).__init__()
+
+        self.testsuites = None
+
+        self.cur_data = ""
+        self.cur_suite = None
+
+        self.stack = []
+
+
+    def start(self, tag, attrs):
+        tag = tag.split('}')[-1] # get rid of the namespace
+
+        obj = None
+
+        if tag == 'testsuites':
+            obj = TestSuites(attrs)
+            self.testsuites = obj
+        elif tag == 'suite':
+            obj = Suite(attrs)
+            self.cur_suite = obj
+            self.testsuites.suites.append(obj)
+        elif tag == 'test':
+            obj = Test(attrs)
+            self.cur_suite.tests.append(obj)
+
+        if tag in self._obj_tags:
+            self.stack.append(obj)
+
+
+    def data(self, data):
+        self.cur_data += data
+
+
+    def end(self, tag):
+        tag = tag.split('}')[-1] # get rid of the namespace
+
+        data = self.cur_data.strip()
+        if len(data):
+            self.stack[-1].attrs[tag] = data
+
+        if tag in self._obj_tags:
+            self.stack.pop()
+
+        self.cur_data = ""
+
+    def close(self):
+        return self.testsuites
+
+
+def main(argv):
+    if len(argv) < 2:
+        print("usage: python %s CheckLog_xcb.xml" % argv[0])
+        return 1
+
+    try:
+        with open(argv[1]) as fh:
+            tree_builder = CheckTreeBuild()
+            parser = XMLParser(target=tree_builder)
+            parse(source=fh, parser=parser)
+
+            testsuites = tree_builder.close()
+            print(testsuites)
+    except FileNotFoundError as e:
+        print("failed to open: %s" % argv[1])
+        return 1
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
-- 
1.8.3.3



More information about the Xcb mailing list