[pypy-svn] r38188 - in pypy/dist: lib-python pypy/tool/pytest pypy/tool/pytest/test

pedronis at codespeak.net pedronis at codespeak.net
Thu Feb 8 18:47:37 CET 2007


Author: pedronis
Date: Thu Feb  8 18:47:34 2007
New Revision: 38188

Modified:
   pypy/dist/lib-python/conftest.py
   pypy/dist/pypy/tool/pytest/genreportdata.py
   pypy/dist/pypy/tool/pytest/htmlreport.py
   pypy/dist/pypy/tool/pytest/overview.py
   pypy/dist/pypy/tool/pytest/result.py
   pypy/dist/pypy/tool/pytest/test/test_new_count.py
   pypy/dist/pypy/tool/pytest/test/test_overview.py
Log:
- have options for lib-python conftest to specify a non default test result directory
  and for -C to specify a different location for the compiled pypy-c

- because of previous checking py.test reports properly -C failures as failures

- with -C use the pypy revision inside the executable used

- use valid header fields names and add sanity checks about that,
  write some code to be able to read the broken old format
  with the email package from 2.4

- genreportdata works with 2.4 now

- the few tests always passes, dont't need to be skipped on 2.4

- genreportdata takes an optional argument which is a testresultdir

- fix some double escaping or broken try at using raw html 
  with genreportdata and newer pylibs



Modified: pypy/dist/lib-python/conftest.py
==============================================================================
--- pypy/dist/lib-python/conftest.py	(original)
+++ pypy/dist/lib-python/conftest.py	Thu Feb  8 18:47:34 2007
@@ -23,6 +23,8 @@
                                       regrtestdir, modregrtestdir, testresultdir
 from pypy.tool.pytest.result import Result, ResultFromMime
 
+pypyexecpath = pypydir.join('bin', 'pypy-c')
+    
 # 
 # Interfacing/Integrating with py.test's collection process 
 #
@@ -37,15 +39,22 @@
 option = py.test.config.addoptions("compliance testing options", 
     Option('-C', '--compiled', action="store_true", 
            default=False, dest="use_compiled", 
-           help="use a compiled version of pypy, expected in pypy/bin/pypy-c"),
+           help="use a compiled version of pypy"),
+    Option('--compiled-pypy', action="store", type="string", dest="pypy_executable",
+           default=str(pypyexecpath),
+           help="to use together with -C to specify the path to the "
+                "compiled version of pypy, by default expected in pypy/bin/pypy-c"),
     Option('-E', '--extracttests', action="store_true", 
            default=False, dest="extracttests", 
            help="try to extract single tests and run them via py.test/PyPy"), 
     Option('-T', '--timeout', action="store", type="string", 
            default="100mp", dest="timeout", 
            help="fail a test module after the given timeout. "
-                "specify in seconds or 'NUMmp' aka Mega-Pystones")
-    ) 
+                "specify in seconds or 'NUMmp' aka Mega-Pystones"),
+    Option('--resultdir', action="store", type="string", 
+           default=str(testresultdir), dest="resultdir", 
+           help="directory under which to store results in USER at HOST subdirs"),
+    )
 
 def gettimeout(): 
     timeout = option.timeout.lower()
@@ -796,15 +805,19 @@
         return 'unknown'  
 
 def getexecutable(_cache={}):
-    execpath = pypydir.join('bin', 'pypy-c')
+    execpath = py.path.local(option.pypy_executable)
     if not _cache:
         text = execpath.sysexec('-c', 
-            'import sys; print sys.version; print sys.pypy_translation_info')
+            'import sys; '
+            'print sys.version; '
+            'print sys.pypy_svn_url; '
+            'print sys.pypy_translation_info; ')
         lines = text.split('\n')
-        assert len(lines) == 3 and lines[2] == ''
-        assert lines[1].startswith('{') and lines[1].endswith('}')
-        info = eval(lines[1])
+        assert len(lines) == 4 and lines[3] == ''
+        assert lines[2].startswith('{') and lines[2].endswith('}')
+        info = eval(lines[2])
         info['version'] = lines[0]
+        info['rev'] = eval(lines[1])[1]
         _cache.update(info)
     return execpath, _cache
 
@@ -827,7 +840,8 @@
         return ReallyRunFileExternal(name, parent=self) 
 
 
-def ensuretestresultdir(): 
+def ensuretestresultdir():
+    testresultdir = py.path.local(option.resultdir)
     if not testresultdir.check(dir=1): 
         py.test.skip("""'testresult' directory not found.
         To run tests in reporting mode (without -E), you first have to
@@ -836,7 +850,6 @@
             testresultdir, ))
     return testresultdir 
 
-
 #
 # testmethod: 
 # invoking in a seprate process: py.py TESTFILE
@@ -929,7 +942,7 @@
                                      "more interesting non-timeout outcome")
             
         fn.write(result.repr_mimemessage().as_string(unixfrom=False))
-        if result['exit status']:  
+        if result['exit-status']:  
              time.sleep(0.5)   # time for a Ctrl-C to reach us :-)
              print >>sys.stderr, result.getnamedtext('stderr') 
              py.test.fail("running test failed, see stderr output below") 
@@ -963,6 +976,7 @@
         result['pypy-revision'] = getrev(pypydir) 
         if option.use_compiled:
             execpath, info = getexecutable()
+            result['pypy-revision'] = info.pop('rev')
             result['executable'] = execpath.basename
             for key, value in info.items():
                 result['executable-%s' % key] = str(value)
@@ -1002,7 +1016,7 @@
         else: 
             outcome = "ERR"
         
-        result['exit status'] = exit_status 
+        result['exit-status'] = exit_status 
         result['outcome'] = outcome 
         return result
 

Modified: pypy/dist/pypy/tool/pytest/genreportdata.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/genreportdata.py	(original)
+++ pypy/dist/pypy/tool/pytest/genreportdata.py	Thu Feb  8 18:47:34 2007
@@ -2,27 +2,29 @@
 import autopath
 import py
 import sys
-if sys.version_info[:2] != (2,3):
-        raise RuntimeError("Genreportdata.py needs Python 2.3")
         
 mydir = py.magic.autopath().dirpath().realpath()
 from pypy.tool.pytest import htmlreport 
 from pypy.tool.pytest import confpath 
 
-if __name__ == '__main__': 
-    testresultdir = confpath.testresultdir 
-    assert testresultdir.check(dir=1)
-    try:
-        resultwc = py.path.svnwc(testresultdir)
-        print "updating", resultwc
-        resultwc.update()
-    except KeyboardInterrupt, RuntimeError:
-        raise
-    except Exception,e: #py.process.ExecutionFailed,e:
-        print >> sys.stderr, "Warning: ",e #Subversion update failed"
+if __name__ == '__main__':
+    if len(sys.argv) > 1:
+        testresultdir = py.path.local(sys.argv[1])
+        assert testresultdir.check(dir=1)        
+    else:
+        testresultdir = confpath.testresultdir 
+        assert testresultdir.check(dir=1)
+        try:
+            resultwc = py.path.svnwc(testresultdir)
+            print "updating", resultwc
+            resultwc.update()
+        except KeyboardInterrupt, RuntimeError:
+            raise
+        except Exception,e: #py.process.ExecutionFailed,e:
+            print >> sys.stderr, "Warning: ",e #Subversion update failed"
 
     print "traversing", mydir 
-    rep = htmlreport.HtmlReport()
+    rep = htmlreport.HtmlReport(testresultdir)
     rep.parselatest()
 
     print "making html files"

Modified: pypy/dist/pypy/tool/pytest/htmlreport.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/htmlreport.py	(original)
+++ pypy/dist/pypy/tool/pytest/htmlreport.py	Thu Feb  8 18:47:34 2007
@@ -14,10 +14,11 @@
 #
 
 html = py.xml.html
+NBSP = py.xml.raw(" ")
 
 class HtmlReport(object): 
-    def __init__(self): 
-        self.resultcache = ResultCache()
+    def __init__(self, resultdir): 
+        self.resultcache = ResultCache(resultdir)
 
     def parselatest(self): 
         self.resultcache.parselatest()
@@ -49,10 +50,10 @@
 
     def render_result_row(self, result): 
         dp = py.path.local(result['fspath']) 
-       
+
         options = " ".join([x for x in result.get('options', []) if x!= 'core'])
         if not options: 
-            options=" "
+            options = NBSP
 
         failureratio = 100 * (1.0 - result.ratio_of_passed())
         return html.tr(
@@ -64,7 +65,7 @@
                 html.td(result['platform']), 
                 html.td("%.2fs" % result['execution-time']),
                 html.td(options), 
-                html.td(result.repr_short_error() or ' ')
+                html.td(result.repr_short_error() or NBSP)
         )
 
     def getrelpath(self, p): 
@@ -89,7 +90,7 @@
         def iscore(result): 
             return 'core' in result.get('options', []) 
         coretests = []
-        noncoretests = [] 
+        noncoretests = []
         for name in self.resultcache.getnames(): 
             result = self.resultcache.getlatestrelevant(name)
             if iscore(result): 
@@ -182,7 +183,6 @@
                 text = result.getnamedtext(name)
             except KeyError: 
                 continue
-            text = py.xml.escape(text)
             self.body.append(html.h3(name))
             self.body.append(html.pre(text))
 

Modified: pypy/dist/pypy/tool/pytest/overview.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/overview.py	(original)
+++ pypy/dist/pypy/tool/pytest/overview.py	Thu Feb  8 18:47:34 2007
@@ -1,9 +1,9 @@
-from pypy.tool.pytest.confpath import testresultdir 
 from pypy.tool.pytest import result 
-
+import sys
 
 class ResultCache: 
-    def __init__(self): 
+    def __init__(self, resultdir):
+        self.resultdir = resultdir
         self.name2result = {}
 
     def parselatest(self): 
@@ -11,16 +11,17 @@
             return p.check(fnmatch='test_*.txt', file=1)
         def rec(p): 
             return p.check(dotfile=0)
-        for x in testresultdir.visit(filefilter, rec): 
+        for x in self.resultdir.visit(filefilter, rec): 
             self.parse_one(x)
     
-    def parse_one(self, resultpath): 
+    def parse_one(self, resultpath):
         try: 
             res = result.ResultFromMime(resultpath) 
             ver = res['testreport-version']
-            if ver != "1.1":
+            if ver != "1.1" and ver != "1.1.1":
                 raise TypeError
-        except TypeError: 
+        except TypeError: # xxx
+            print >>sys.stderr, "could not parse %s" % resultpath
             return
         name = res.testname 
         print name
@@ -35,7 +36,7 @@
         resultlist = self.name2result[name]
         maxrev = 0
         maxresult = None
-        for res in resultlist: 
+        for res in resultlist:
             resrev = res['pypy-revision']
             if resrev == 'unknown': 
                 continue 

Modified: pypy/dist/pypy/tool/pytest/result.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/result.py	(original)
+++ pypy/dist/pypy/tool/pytest/result.py	Thu Feb  8 18:47:34 2007
@@ -52,7 +52,10 @@
         items = self._headers.items()
         items.sort()
         reprs = {}
-        for name, value in items: 
+        for name, value in items:
+            assert ':' not in name
+            chars = map(ord, name)
+            assert min(chars) >= 33 and max(chars) <= 126
             outer[name] = str(value) 
             if not isinstance(value, str): 
                 typename = type(value).__name__ 
@@ -105,17 +108,40 @@
     def istimeout(self): 
         return self['outcome'].lower() == 't/o'
 
+# XXX backward compatibility
+def sanitize(msg, path):
+    if 'exit-status' in msg.keys():
+        return msg
+    f = open(str(path), 'r')
+    msg = f.read()
+    f.close()    
+    for broken in ('exit status', 'cpu model', 'cpu mhz'):
+        valid = broken.replace(' ','-')
+        invalid = msg.find(broken+':')
+        msg = (msg[:invalid] + valid +
+               msg[invalid+len(valid):])
+    from email import message_from_string
+    msg = message_from_string(msg)
+    return msg
+
+def sanitize_reprs(reprs):
+    if 'exit status' in reprs:
+        reprs['exit-status'] = reprs.pop('exit status')
+            
 class ResultFromMime(Result): 
     def __init__(self, path): 
         super(ResultFromMime, self).__init__(init=False) 
-        f = open(str(path), 'r') 
-        from email import message_from_file 
+        f = open(str(path), 'r')
+        from email import message_from_file
         msg = message_from_file(f)
+        f.close()
+        msg = sanitize(msg, path)
         # XXX security wise evil (keep in mind once we accept reporsts
         # from anonymous
         #print msg['_reprs']
-        self._reprs = eval(msg['_reprs']) 
+        self._reprs = eval(msg['_reprs'])
         del msg['_reprs']
+        sanitize_reprs(self._reprs)
         for name, value in msg.items(): 
             if name in self._reprs: 
                 value = eval(value)  # XXX security
@@ -132,7 +158,7 @@
         payload = msg.get_payload() 
         if payload: 
            for submsg in payload: 
-                assert submsg.get_main_type() == 'text'
+                assert submsg.get_content_type() == 'text/plain'
                 fn = submsg.get_filename() 
                 assert fn
                 # XXX we need to deal better with encodings to
@@ -165,14 +191,14 @@
     except:
         username = 'unknown'
     userhost = '%s@%s' % (username, socket.gethostname())
-    result['testreport-version'] = "1.1" 
+    result['testreport-version'] = "1.1.1"
     result['userhost'] = userhost 
     result['platform'] = sys.platform 
     result['python-version-info'] = sys.version_info 
     info = try_getcpuinfo() 
     if info is not None:
-        result['cpu model'] = info.get('model name', "unknown")
-        result['cpu mhz'] = info.get('cpu mhz', 'unknown')
+        result['cpu-model'] = info.get('model name', "unknown")
+        result['cpu-mhz'] = info.get('cpu mhz', 'unknown')
 #
 #
 #

Modified: pypy/dist/pypy/tool/pytest/test/test_new_count.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/test/test_new_count.py	(original)
+++ pypy/dist/pypy/tool/pytest/test/test_new_count.py	Thu Feb  8 18:47:34 2007
@@ -5,9 +5,6 @@
 testpath = py.magic.autopath().dirpath('data')
 
 class TestResultCache:
-    def setup_class(self):
-        if py.std.sys.version_info >= (2,4): 
-            py.test.skip("does not work on python 2.4 and greater currently")
 
     def test_timeout(self):
         test = ResultFromMime(testpath.join('test___all__.txt'))

Modified: pypy/dist/pypy/tool/pytest/test/test_overview.py
==============================================================================
--- pypy/dist/pypy/tool/pytest/test/test_overview.py	(original)
+++ pypy/dist/pypy/tool/pytest/test/test_overview.py	Thu Feb  8 18:47:34 2007
@@ -7,7 +7,7 @@
     def setup_class(cls): 
         if not testresultdir.check(dir=1):
             py.test.skip("testresult directory not checked out")
-        cls.rc = ResultCache() 
+        cls.rc = ResultCache(testresultdir) 
         cls.rc.parselatest()
 
     def test_getlatest_all(self): 



More information about the Pypy-commit mailing list