[py-svn] r10665 - in py/branch/py-collect: . test test/terminal test/testing

hpk at codespeak.net hpk at codespeak.net
Fri Apr 15 13:43:30 CEST 2005


Author: hpk
Date: Fri Apr 15 13:43:29 2005
New Revision: 10665

Modified:
   py/branch/py-collect/conftest.py
   py/branch/py-collect/test/config.py
   py/branch/py-collect/test/defaultconftest.py
   py/branch/py-collect/test/terminal/out.py
   py/branch/py-collect/test/terminal/remote.py
   py/branch/py-collect/test/terminal/terminal.py
   py/branch/py-collect/test/testing/test_session.py
Log:
- make remote execution / looponfailing work again
  (with the new execnet redirect mechanism, works 
  kind of nice) 

- internally rename 'exitfirstproblem' to 'exitfirst' 



Modified: py/branch/py-collect/conftest.py
==============================================================================
--- py/branch/py-collect/conftest.py	(original)
+++ py/branch/py-collect/conftest.py	Fri Apr 15 13:43:29 2005
@@ -11,7 +11,7 @@
 verbose = 0
 nocapture = False
 collectonly = False
-exitfirstproblem = False
+exitfirst = False
 fulltrace = False
 showlocals = False
 nomagic = False

Modified: py/branch/py-collect/test/config.py
==============================================================================
--- py/branch/py-collect/test/config.py	(original)
+++ py/branch/py-collect/test/config.py	Fri Apr 15 13:43:29 2005
@@ -59,12 +59,15 @@
         """ 
         configpaths = guessconfigpaths(*getanchorpaths(args))
         config = bootstrapconfig(configpaths) 
+        config._origargs = args
         cmdlineoption, remaining = config._parser.parse_args(args) 
         for name, value in vars(cmdlineoption).items(): 
             setattr(config.option, name, value) 
         fixoptions(config.option) 
         if not remaining: 
             remaining.append(py.std.os.getcwd()) 
+        print "remaining is", remaining
+        config.remaining = remaining 
         return config, remaining 
     parse = classmethod(parse) 
 
@@ -118,7 +121,9 @@
         raise ValueError, "--exec together with --pdb not supported yet."
 
     # setting a correct executable
+    remote = False
     if option.executable is not None:
+        remote = True 
         exe = py.path.local(py.std.os.path.expanduser(option.executable))
         if not exe.check():
             exe = py.path.local.sysfind(option.executable)
@@ -127,6 +132,10 @@
     else: 
         option.executable = py.std.sys.executable 
 
+    # make information available about wether we should/will be remote 
+    option._remote = remote or option.looponfailing
+    option._fromremote = False 
+
     # setting a correct frontend session 
     if option.session:
         name = option.session

Modified: py/branch/py-collect/test/defaultconftest.py
==============================================================================
--- py/branch/py-collect/test/defaultconftest.py	(original)
+++ py/branch/py-collect/test/defaultconftest.py	Fri Apr 15 13:43:29 2005
@@ -19,7 +19,7 @@
                action="count", dest="verbose", default=0,
                help="increase verbosity"),
         Option('-x', '--exitfirst',
-               action="store_true", dest="exitfirstproblem", default=False,
+               action="store_true", dest="exitfirst", default=False,
                help="exit instantly on first error or failed test."),
         Option('-s', '--nocapture',
                action="store_true", dest="nocapture", default=False,

Modified: py/branch/py-collect/test/terminal/out.py
==============================================================================
--- py/branch/py-collect/test/terminal/out.py	(original)
+++ py/branch/py-collect/test/terminal/out.py	Fri Apr 15 13:43:29 2005
@@ -73,7 +73,7 @@
     if file is None: 
         file = py.std.sys.stdout 
     elif hasattr(file, 'send'): 
-        file = WriteFile(file) 
+        file = WriteFile(file.send) 
     if hasattr(file, 'isatty') and file.isatty(): 
         return TerminalOut(file)
     else:

Modified: py/branch/py-collect/test/terminal/remote.py
==============================================================================
--- py/branch/py-collect/test/terminal/remote.py	(original)
+++ py/branch/py-collect/test/terminal/remote.py	Fri Apr 15 13:43:29 2005
@@ -1,8 +1,7 @@
 from __future__ import generators
 import py
-from py.__impl__.execnet.channel import ChannelFile, receive2file
-from py.__impl__.test.config import configbasename
-from py.__impl__.test.collect import getfscollector
+from py.__impl__.execnet.channel import ChannelFile 
+from py.__impl__.test.terminal.out import getout 
 import sys
 
 def checkpyfilechange(rootdir, statcache={}):
@@ -36,29 +35,6 @@
         for x in self._faileditems:
             yield x
 
-
-class StdouterrProxy:
-    def __init__(self, gateway):
-        self.gateway = gateway
-    def setup(self):
-        channel = self.gateway.remote_exec("""
-            import sys
-            out, err = channel.newchannel(), channel.newchannel()
-            channel.send(out)
-            channel.send(err)
-            sys.stdout, sys.stderr = out.open('w'), err.open('w')
-        """)
-        self.stdout = channel.receive()
-        self.stderr = channel.receive()
-        channel.waitclose(1.0)
-        py.std.threading.Thread(target=receive2file,
-                                args=(self.stdout, sys.stdout)).start()
-        py.std.threading.Thread(target=receive2file,
-                                args=(self.stderr, sys.stderr)).start()
-    def teardown(self):
-        self.stdout.close()
-        self.stderr.close()
-
 def waitfinish(channel):
     try:
         while 1:
@@ -67,37 +43,27 @@
             except (IOError, py.error.Error):
                 continue
             else:
-                failures = channel.receive()
-                return failures
-            break
+                return channel.receive()
     finally:
         #print "closing down channel and gateway"
         channel.close()
         channel.gateway.exit()
 
-def failure_master(executable, args, failures):
-    gw = py.execnet.PopenGateway(executable) 
-    outproxy = StdouterrProxy(gw)
-    outproxy.setup()
-    try:
-        channel = gw.remote_exec("""
-            from py.__impl__.test.run import failure_slave
-            failure_slave(channel) 
-        """)
-        channel.send((args, failures))
-        return waitfinish(channel)
-    finally:
-        outproxy.teardown()
-
 def failure_slave(channel):
     """ we run this on the other side. """
     args, failures = channel.receive()
-    sessionclass, config = py.test.init(args, ignoreremote=True) 
+    config, args = py.test.Config.parse(args) 
+    # making this session definitely non-remote 
+    config.option.executable = py.std.sys.executable 
+    config.option.looponfailing = False 
+    config.option._remote = False 
+    config.option._fromremote = True 
     if failures: 
         cols = getfailureitems(failures)
     else:
-        cols = config.paths 
-    session = sessionclass(config) 
+        cols = args 
+    print "processing", cols
+    session = py.test.TerminalSession(config)
     session.shouldclose = channel.isclosed 
     failures = session.main(cols) 
     channel.send(failures)
@@ -124,23 +90,53 @@
             l.append(current) 
     return l
 
-class TerminalFrontendSession: 
-    def main(self, *args): 
-        # XXX figure out a better rootdir? 
-        rootdir = py.path.local() 
-        failures = []
-        while 1:
-            if self.config.option.looponfailing: 
-                while not checkpyfilechange(rootdir):
-                    py.std.time.sleep(0.4)
-            failures = failure_master(self.config.option.executable or sys.executable, 
-                                      self.args, failures)
-            if not self.config.option.session: 
-                break
-            print "#" * 60
-            print "# session mode: %d failures remaining" % len(failures)
-            for root, names in failures:
-                name = "/".join(names) # XXX
-                print "Failure at: %r" % (name,) 
-            print "#    watching py files below %s" % rootdir
-            print "#                           ", "^" * len(str(rootdir))
+def failure_master(executable, out, args, failures):
+    gw = py.execnet.PopenGateway(executable) 
+    channel = gw.remote_exec("""
+        from py.__impl__.test.terminal.remote import failure_slave
+        failure_slave(channel) 
+    """, stdout=out, stderr=out) 
+    channel.send((args, failures))
+    return waitfinish(channel)
+
+def getrootdir(args): 
+    colitems = py.test.TerminalSession._map2colitems(args) 
+    tops = [x.listchain()[0].fspath for x in colitems]
+    def generalize(p1, p2): 
+        general = p1 
+        for x, y in zip(p1.parts(), p2.parts()): 
+            if x != y: 
+                break 
+            general = x 
+        return general 
+    return reduce(generalize, tops) 
+
+def main(config, file, args): 
+    """ testing process and output happens at a remote place. """ 
+    assert file  
+    if hasattr(file, 'write'): 
+        def out(data): 
+            file.write(data) 
+            file.flush() 
+    else: 
+        out = file 
+    failures = []
+    args = list(args)
+    rootdir = getrootdir(config.remaining) 
+    print "rootdir", rootdir
+    while 1:
+        if config.option.looponfailing: 
+            while not checkpyfilechange(rootdir):
+                py.std.time.sleep(0.4)
+        print "sending", args
+        failures = failure_master(config.option.executable, out, args, failures)
+        if not config.option.looponfailing: 
+            break
+        print "#" * 60
+        print "# looponfailing: mode: %d failures remaining" % len(failures)
+        for root, names in failures:
+            name = "/".join(names) # XXX
+            print "Failure at: %r" % (name,) 
+        print "#    watching py files below %s" % rootdir
+        print "#                           ", "^" * len(str(rootdir))
+

Modified: py/branch/py-collect/test/terminal/terminal.py
==============================================================================
--- py/branch/py-collect/test/terminal/terminal.py	(original)
+++ py/branch/py-collect/test/terminal/terminal.py	Fri Apr 15 13:43:29 2005
@@ -7,10 +7,20 @@
 class TerminalSession(py.test.Session): 
     def __init__(self, config, file=None): 
         super(TerminalSession, self).__init__(config) 
+        if file is None: 
+            file = py.std.sys.stdout 
+        self._file = file
         self.out = getout(file) 
         self._started = {}
         self._opencollectors = []
 
+    def main(self, args): 
+        if self.config.option._remote: 
+            from py.__impl__.test.terminal import remote 
+            remote.main(self.config, self._file, self.config._origargs)
+        else: 
+            super(TerminalSession, self).main(args) 
+
     # ---------------------
     # PROGRESS information 
     # ---------------------
@@ -88,7 +98,7 @@
                        result.excinfo.value))
                 pdb.post_mortem(result.excinfo._excinfo[2])
         if isinstance(result, (colitem.Failed,)): 
-            if self.config.option.exitfirstproblem:
+            if self.config.option.exitfirst:
                 py.test.exit("exit on first problem configured.", item=colitem)
         if result is None or not isinstance(colitem, py.test.Item): 
             if isinstance(colitem, py.test.collect.Module) \
@@ -112,12 +122,15 @@
         super(TerminalSession, self).header(colitems) 
         self.out.sep("=", "test process starts")
         option = self.config.option 
-        if option.looponfailing:
-            mode = 'session/child process'
-        elif option.executable:
-            mode = 'child process'
+        modes = []
+        for name in 'looponfailing', 'exitfirst', 'nomagic': 
+            if getattr(option, name): 
+                modes.append(name) 
+        if option._fromremote:
+            modes.insert(0, 'child process') 
         else:
-            mode = 'inprocess'
+            modes.insert(0, 'inprocess')
+        mode = "/".join(modes)
         self.out.line("testing-mode: %s" % mode)
         self.out.line("executable:   %s  (%s)" %
                           (py.std.sys.executable, repr_pythonversion()))

Modified: py/branch/py-collect/test/testing/test_session.py
==============================================================================
--- py/branch/py-collect/test/testing/test_session.py	(original)
+++ py/branch/py-collect/test/testing/test_session.py	Fri Apr 15 13:43:29 2005
@@ -50,7 +50,7 @@
 
     def test_exit_first_problem(self): 
         session = self.session 
-        session.config.option.exitfirstproblem = True 
+        session.config.option.exitfirst = True 
         session.main([str(datadir / 'filetest.py')])
         l = session.getresults(py.test.Item.Failed)
         assert len(l) == 1 



More information about the pytest-commit mailing list