[py-svn] r31862 - py/branch/distributed/py/test/rsession

fijal at codespeak.net fijal at codespeak.net
Thu Aug 31 00:59:45 CEST 2006


Author: fijal
Date: Thu Aug 31 00:59:43 2006
New Revision: 31862

Modified:
   py/branch/distributed/py/test/rsession/rsession.py
   py/branch/distributed/py/test/rsession/web.py
   py/branch/distributed/py/test/rsession/webjs.py
Log:
Added version of web server which can show failure traceback/skipping reasons. Direct links to svn might be a + as well :-)
Some stuff needs improvement (stdout/stderr), altough it's relatively unclear how to clean up the web server (click it? make browser cache stuff?)
At some point we might want to have web server working for multiple viewers as well.


Modified: py/branch/distributed/py/test/rsession/rsession.py
==============================================================================
--- py/branch/distributed/py/test/rsession/rsession.py	(original)
+++ py/branch/distributed/py/test/rsession/rsession.py	Thu Aug 31 00:59:43 2006
@@ -8,6 +8,7 @@
 import threading
 import sys
 import re
+import time
 
 from py.__.test.rsession import report
 from py.__.test.rsession.master import (
@@ -262,6 +263,10 @@
         reporter(report.TestFinished())
         if startserverflag:
             from py.__.test.rsession.web import kill_server
+            #try:
+            #    while 1:
+            #        time.sleep(.3)
+            #except KeyboardInterrupt:
             kill_server()
         
     def make_colitems(paths, baseon): 

Modified: py/branch/distributed/py/test/rsession/web.py
==============================================================================
--- py/branch/distributed/py/test/rsession/web.py	(original)
+++ py/branch/distributed/py/test/rsession/web.py	Thu Aug 31 00:59:43 2006
@@ -7,7 +7,7 @@
 
 from _findpy import py
 import thread, threading
-
+import re
 
 from pypy.translator.js import commproxy
 
@@ -30,7 +30,7 @@
 
 def escape(s):
     return s.replace("&", "&").replace("<", "<").replace(">", ">"). \
-        replace("'", "\\'").replace(" ", " ")
+        replace("'", "\\'").replace(" ", " ").replace("\n", "<br/>")
 
 
 class ExportedMethods(BasicExternal):
@@ -39,6 +39,8 @@
         self.pending_events = Queue.Queue()
         self.start_event = threading.Event()
         self.end_event = threading.Event()
+        self.skip_reasons = {}
+        self.fail_reasons = {}
     
     def findmodule(self, item):
         # find the most outwards parent which is module
@@ -54,6 +56,14 @@
         self.start_event.wait()
         return json.write(self.hosts)
     
+    @described(retval="aa")
+    def show_skip(self, item_name="a"):
+        return json.write(escape(self.skip_reasons[item_name]))
+    
+    @described(retval="aa")
+    def show_fail(self, item_name="a"):
+        return json.write(escape(str(self.fail_reasons[item_name])))
+    
     @described(retval={"aa":"aa"})
     def show_status_change(self):
         def add_item(event):
@@ -71,13 +81,20 @@
         # some dispatcher here
         if isinstance(event, report.ReceivedItemOutcome):
             args = {}
-            for key, val in event.outcome.__dict__.iteritems():
+            outcome = event.outcome
+            for key, val in outcome.__dict__.iteritems():
                 args[key] = str(val)
             args.update(add_item(event))
             mod = self.findmodule(event.item)
             assert mod is not None, "We should have some parent module"
             args['modulename'] = str(mod.name)
             args['fullmodulename'] = str("/".join(mod.listnames()))
+            fullitemname = args['fullitemname']
+            if outcome.skipped:
+                self.skip_reasons[fullitemname] = outcome.skipped
+            elif outcome.excinfo:
+                self.fail_reasons[fullitemname] = self.repr_failure_tblong(\
+                    event.item, outcome.excinfo, outcome.excinfo.traceback)
         elif isinstance(event, report.ItemStart):
             args = add_item(event)
         elif isinstance(event, report.HostReady):
@@ -88,6 +105,24 @@
         args['type'] = event.__class__.__name__
         return json.write(args)
 
+    def repr_failure_tblong(self, item, excinfo, traceback):
+        lines = []
+        for index, entry in py.builtin.enumerate(traceback): 
+            lines.append('----------')
+            lines.append("%s: %s" % (entry.path, entry.lineno))
+            lines += self.repr_source(entry.relline, entry.source)
+        lines.append("%s: %s" % (excinfo.typename, excinfo.value))
+        return "\n".join(lines)
+    
+    def repr_source(self, relline, source):
+        lines = []
+        for num, line in enumerate(source.split("\n")):
+            if num == relline:
+                lines.append(">>>>" + line)
+            else:
+                lines.append("    " + line)
+        return lines
+
     def report_ReceivedItemOutcome(self, event):
         self.pending_events.put(event)
     
@@ -133,16 +168,34 @@
             path = path[:-1]
         if path.startswith("/"):
             path = path[1:]
+        m = re.match('^(.*)\?(.*)$', path)
+        if m:
+            path = m.group(1)
+            getargs = m.group(2)
+        else:
+            getargs = ""
         method_to_call = getattr(self, "run_" + path, None)
         if method_to_call is None:
             exec_meth = getattr(exported_methods, path, None)
             if exec_meth is None:
                 self.send_error(404, "File %s not found" % path)
             else:
-                self.serve_data('text/json', exec_meth())
+                self.serve_data('text/json', exec_meth(**self.parse_args(getargs)))
         else:
             method_to_call()
     
+    def parse_args(self, getargs):
+        # parse get argument list
+        if getargs == "":
+            return {}
+        
+        args = {}
+        arg_pairs = getargs.split("&")
+        for arg in arg_pairs:
+            key, value = arg.split("=")
+            args[key] = value
+        return args
+    
     do_POST = do_GET
     
     def run_(self):
@@ -154,7 +207,7 @@
     
     def run_jssource(self):
         from py.__.test.rsession import webjs
-        self.serve_data("text/javascript", rpython2javascript(webjs, ["main"]))
+        self.serve_data("text/javascript", rpython2javascript(webjs, ["main", "show_skip", "show_traceback"]))
     
     def serve_data(self, content_type, data):
         self.send_response(200)

Modified: py/branch/distributed/py/test/rsession/webjs.py
==============================================================================
--- py/branch/distributed/py/test/rsession/webjs.py	(original)
+++ py/branch/distributed/py/test/rsession/webjs.py	Thu Aug 31 00:59:43 2006
@@ -37,14 +37,24 @@
             if msg["passed"] == 'True':
                 td.innerHTML = "."
             elif msg["skipped"] != 'None':
-                td.innerHTML = "s"
+                td.innerHTML = '<a href="javascript:show_skip(\''+msg['fullitemname']+'\')">s</a>'
             else:
-                td.innerHTML = 'F'
+                td.innerHTML = '<a href="javascript:show_traceback(\''+msg['fullitemname']+'\')">F</a>'
             module_part.appendChild(td)
         except:
             dom.get_document().getElementById("testmain").innerHTML += "some error"
     exported_methods.show_status_change(comeback)
 
+def show_skip(item_name="a"):
+    exported_methods.show_skip(item_name, show_skip_come_back)
+
+def show_skip_come_back(skipped_data):
+    msgbox = get_elem("messagebox")
+    msgbox.innerHTML = skipped_data
+
+def show_traceback(item_name="a"):
+    exported_methods.show_fail(item_name, show_skip_come_back)
+
 def host_init(host_list):
     elem = dom.get_document().getElementById("hostrow")
     for host in host_list:



More information about the pytest-commit mailing list